package org.jeecg.modules.asset.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.asset.entity.AssetContractInfo;
import org.jeecg.modules.asset.entity.AssetLedger;
import org.jeecg.modules.asset.entity.AssetMessage;
import org.jeecg.modules.asset.service.IAssetContractInfoService;
import org.jeecg.modules.asset.service.IAssetLedgerService;
import org.jeecg.modules.asset.service.IAssetMessageService;
import org.jeecg.modules.system.entity.SysPermission;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysRoleService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @Description: 驾驶舱统计
* @Date:   2025-11-09
* @Version: V1.0
*/
@Api(tags="驾驶舱统计")
@RestController
@RequestMapping("/asset/Statistics")
@Slf4j
public class StatisticsController extends JeecgController<AssetLedger, IAssetLedgerService> {
   @Autowired
   private IAssetLedgerService assetLedgerService;
   @Autowired
   private IAssetMessageService assetMessageService;
   @Autowired
   private IAssetContractInfoService contractInfoService;
   @Autowired
   private ISysUserService sysUserService;
   @Autowired
   private ISysRoleService sysRoleService;
   @Autowired
   private ISysUserRoleService sysUserRoleService;
   @Autowired
   private ISysDictService sysDictService;

    /**
     * 资产台账统计
     */
    @ApiOperation(value="资产台账统计", notes="资产台账统计")
    @GetMapping(value = "/assetTotal")
    public Result<Map<String, Object>> indexTotal() {
        Map<String, Object> map = new HashMap<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        // 空间资产数量
        List<AssetMessage> spaceAssetList = assetMessageService.list(queryWrapper.eq("type", 1));
        map.put("spaceAssetTotal", spaceAssetList.size());
        // 设备资产数量
        queryWrapper.clear();
        List<AssetMessage> equipAssetList = assetMessageService.list(queryWrapper.eq("type", 2));
        map.put("equipAssetTotal", equipAssetList.size());
        // 总资产面积
        double buildingArea = spaceAssetList.stream()
                .filter(asset -> asset.getBuildingArea() != null)
                .mapToDouble(asset -> Double.parseDouble(asset.getBuildingArea().toString()))
                .sum();
        map.put("buildingArea", new DecimalFormat("0").format(buildingArea));
//        double usedFloorArea = spaceAssetList.stream()
//                .filter(asset -> asset.getFloorArea() != null && asset.getStatus().equals("1"))
//                .mapToDouble(asset -> Double.parseDouble(asset.getFloorArea()))
//                .sum();
//        double allFloorArea = spaceAssetList.stream()
//                .filter(asset -> asset.getFloorArea() != null)
//                .mapToDouble(asset -> Double.parseDouble(asset.getFloorArea()))
//                .sum();
//        if (allFloorArea != 0){
//            //百分比 保留两位小数
//            map.put("spaceUseRate", new DecimalFormat("0").format(usedFloorArea / allFloorArea * 100));
//        }else {
//            map.put("spaceUseRate", "0");
//        }
        // 总资产价值
        queryWrapper.clear();
        List<AssetMessage> allAssetList = assetMessageService.list();
        double sum = allAssetList.stream()
                .filter(asset -> asset.getBookOriginalValue() != null)
                .mapToDouble(asset -> Double.parseDouble(asset.getBookOriginalValue().toString()))
                .sum();
        // 亿元
        map.put("price", new DecimalFormat("0.00").format(sum / 100000000));
        return Result.OK(map);
    }

    /**
     * 资产价值排名
     */
    @ApiOperation(value="资产价值排名", notes="资产价值排名")
    @GetMapping(value = "/assetPriceRank")
    public Result<List<Map<String, Object>>> assetPriceRank() {
        List<Map<String, Object>> list = new ArrayList<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        // 空间资产
        List<AssetMessage> assetMessageList = assetMessageService.list(queryWrapper
                .eq("type", 1)
                .orderByDesc("book_original_value")
                .last("limit 6"));
//        for (AssetLedger asset : spaceAssetList){
//            queryWrapper.clear();
//            List<AssetLedger> assetLedgers = assetLedgerService.list(queryWrapper.eq("position", asset.getId()));
//            double sum = assetLedgers.stream()
//                    .filter(asset1 -> asset1.getPrice() != null)
//                    .mapToDouble(asset1 -> Double.parseDouble(asset1.getPrice()))
//                    .sum();
//            double price = asset.getPrice() == null ? 0 : Double.parseDouble(asset.getPrice());
//            Map<String, Object> map = new HashMap<>();
//            map.put("name", asset.getName());
//            // 亿元
//            map.put("value", new DecimalFormat("0.0").format((sum + price)/100000000));
//            list.add(map);
//        }
        for (AssetMessage asset : assetMessageList){
            Map<String, Object> map = new HashMap<>();
            map.put("name", asset.getAssetName());
            // 亿元
            BigDecimal bookOriginal = asset.getBookOriginalValue() == null ? BigDecimal.ZERO : asset.getBookOriginalValue();
            map.put("value", new DecimalFormat("0.0").format((Double.parseDouble(bookOriginal.toString()))/100000000));
            list.add(map);
        }
        // list value 倒排序
//        list.sort((o1, o2) -> {
//            return (Double.parseDouble(o1.get("value").toString()) - Double.parseDouble(o2.get("value").toString()) < 0 ? 1 : -1);
//        });
//        list = list.stream().limit(6).collect(Collectors.toList());
        return Result.OK(list);
    }

    /**
     * 获取设备类型
     */
    @ApiOperation(value="获取设备类型", notes="获取设备类型")
    @GetMapping(value = "/getEqType")
    public Result<List<Map>> getEqType() {
        List<DictModel> items = sysDictService.getDictItems("asset_equip_type");
        List<Map> list = new ArrayList<>();
        items.forEach(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("label", item.getLabel());
            map.put("value", "equip"+item.getValue());
            list.add( map);
        });
        return Result.OK(list);
    }

    /**
     * 设备资产类型统计
     */
    @ApiOperation(value="设备资产类型统计", notes="设备资产类型统计")
    @GetMapping(value = "/assetEqType")
    public Result<List<Map<String, Object>>> assetEqType() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map allMap = new HashMap<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        long count = assetMessageService.count(queryWrapper.eq("type", 2));
        allMap.put("name", "all");
        allMap.put("value", count);
        list.add(allMap);
        List<DictModel> items = sysDictService.getDictItems("equipment_asset_status");
        items.forEach(item -> {
            queryWrapper.clear();
            long count1 = assetMessageService.count(queryWrapper.eq("type", 2).eq("status", item.getValue()));
            Map<String, Object> map = new HashMap<>();
            map.put("name", "equip"+item.getValue());
            map.put("label", item.getLabel());
            map.put("value", count1);
            list.add( map);
        });
        return Result.OK(list);
    }

    /**
     * 空间资产运营情况统计
     */
    @ApiOperation(value="空间资产运营情况统计", notes="空间资产运营情况统计")
    @GetMapping(value = "/assetBuildStatus")
    public Result<List<Map<String, Object>>> assetBuildStatus() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map allMap = new HashMap<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        long count = assetMessageService.count(queryWrapper.eq("type", 1));
        allMap.put("name", "all");
        allMap.put("value", count);
        list.add(allMap);
        List<DictModel> items = sysDictService.getDictItems("space_asset_status");
        items.forEach(item -> {
            queryWrapper.clear();
            long count1 = assetMessageService.count(queryWrapper.eq("type", 1).eq("status", item.getValue()));
            Map<String, Object> map = new HashMap<>();
            map.put("name", "build"+item.getValue());
            map.put("label", item.getLabel());
            map.put("value", count1);
            list.add( map);
        });
        return Result.OK(list);
    }

    /**
     * 人员部门统计
     */
    @ApiOperation(value="人员部门统计", notes="人员部门统计")
    @GetMapping(value = "/roleUserTotal")
    public Result<List<Map<String, Object>>> roleUserTotal() {
        List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().ne("role_code", "admin"));
        List<Map<String, Object>> list = new ArrayList<>();
        Map allMap = new HashMap<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        allMap.put("name", "all");
        allMap.put("value", roleList.size());
        list.add(allMap);
        roleList.forEach(item -> {
            Page<SysUser> page = new Page<>(1, 1);
            IPage<SysUser> userList = sysUserService.getUserByRoleId(page, item.getId(), null);
            Map<String, Object> map = new HashMap<>();
            map.put("label", item.getRoleName());
            map.put("value", userList.getTotal());
            list.add( map);
        });
        return Result.OK(list);
    }


    /**
     * 资产说明
     */
    @ApiOperation(value="资产说明", notes="资产说明")
    @GetMapping(value = "/assetRemarks")
    public Result<List<Map<String, Object>>> assetRemarks() {
        List<Map<String, Object>> list = new ArrayList<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        // 空间资产
        List<AssetMessage> spaceAssetList = assetMessageService.list(queryWrapper.eq("type", 1));
        for (AssetMessage asset : spaceAssetList){
            queryWrapper.clear();
            List<AssetMessage> assetLedgers = assetMessageService.list(queryWrapper.eq("belong_space_code", asset.getId()));
            Map<String, Object> map = new HashMap<>();
            map.put("code", asset.getAssetCode());
            map.put("name", asset.getAssetName());
            map.put("position", asset.getPlace());
            map.put("floorArea", asset.getBuildingArea());
            map.put("eqNum", assetLedgers.size());
            map.put("value", asset.getBookOriginalValue() == null ? 0 :
                    new DecimalFormat("0.0").format((Double.parseDouble(asset.getBookOriginalValue().toString()))/100000000));
            list.add(map);
        }
        // list value 正排序
        list.sort((o1, o2) -> {
            return (Double.parseDouble(o1.get("value").toString()) - Double.parseDouble(o2.get("value").toString()) < 0 ? 1 : -1);
        });
        return Result.OK(list);
    }

    /**
     * 设备资产运维情况统计
     */
    @ApiOperation(value="设备资产运维情况统计", notes="设备资产运维情况统计")
    @GetMapping(value = "/assetEqStatus")
    public Result<List<Map<String, Object>>> assetEqStatus() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map allMap = new HashMap<>();
        QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
        long count = assetMessageService.count(queryWrapper.eq("type", 2));
        List<DictModel> items = sysDictService.getDictItems("equipment_asset_status");
        items.forEach(item -> {
            queryWrapper.clear();
            long count1 = assetMessageService.count(queryWrapper.eq("type", 2).eq("status", item.getValue()));
            Map<String, Object> map = new HashMap<>();
            map.put("name", item.getLabel());
            map.put("value", count1);
            list.add( map);
        });
        // list value 正排序
        list.sort((o1, o2) -> {
            return (Double.parseDouble(o1.get("value").toString()) - Double.parseDouble(o2.get("value").toString()) > 0 ? 1 : -1);
        });
        return Result.OK(list);
    }


    /**
     * 资产价值雷达图
     */
    @ApiOperation(value="资产价值雷达图", notes="资产价值雷达图")
    @GetMapping(value = "/assetRadar")
    public Result<List<Map<String, Object>>> assetRadar() {
        List<Map<String, Object>> list = new ArrayList<>();
        QueryWrapper<AssetLedger> queryWrapper = new QueryWrapper<>();
        // 空间资产
        List<AssetLedger> spaceAssetList = assetLedgerService.list(queryWrapper.eq("type", 1));
        for (AssetLedger asset : spaceAssetList){
            queryWrapper.clear();
            List<AssetLedger> assetLedgers = assetLedgerService.list(queryWrapper.eq("position", asset.getId()));
            double sum = assetLedgers.stream()
                    .filter(asset1 -> asset1.getPrice() != null)
                    .mapToDouble(asset1 -> Double.parseDouble(asset1.getPrice()))
                    .sum();
            double price = asset.getPrice() == null ? 0 : Double.parseDouble(asset.getPrice());
            Map<String, Object> map = new HashMap<>();
            map.put("name", asset.getName());
            // 亿元
            map.put("value", (sum + price)/100000000);
            list.add(map);
        }
        List<Map<String, Object>> radarData = new ArrayList<>();
        String radarName = "< 1亿,1-2亿,2-3亿,3-4亿,4-5亿,> 5亿";
        String radarValue = "1,2,3,4,5,6";
        String[] split = radarValue.split(",");
        for (int i=0; i < radarName.split(",").length; i++ ){
            String name = radarName.split(",")[i];
            Map<String, Object> map = new HashMap<>();
            map.put("name", name);
            if (i == 0){
                String start = split[i];
                long count = list.stream().filter(item -> new BigDecimal(item.get("value").toString()).compareTo(new BigDecimal(start)) < 0).count();
                map.put("value", count);
            }else if (i == 5){
                String start = split[i-1];
                long count = list.stream().filter(item -> new BigDecimal(item.get("value").toString()).compareTo(new BigDecimal(start)) >= 0).count();
                map.put("value", count);
            }else {
                String start = split[i-1];
                String end = split[i];
                long count = list.stream().filter(item -> new BigDecimal(item.get("value").toString()).compareTo(new BigDecimal(start)) >= 0
                        && new BigDecimal(item.get("value").toString()).compareTo(new BigDecimal(end)) < 0).count();
                map.put("value", count);
            }
            radarData.add( map);
        }
        return Result.OK(radarData);
    }

    /**
     * 设备资产类别统计
     */
    @ApiOperation(value="设备资产类别统计", notes="设备资产类别统计")
    @GetMapping(value = "/assetEquipType")
    public Result<List<Map<String, Object>>> assetEquipType() {
        List<Map<String, Object>> list = new ArrayList<>();
        List<DictModel> items = sysDictService.getDictItems("asset_equip_type");
        items.forEach(item -> {
            QueryWrapper<AssetMessage> queryWrapper = new QueryWrapper<>();
            long count1 = assetMessageService.count(queryWrapper.eq("type", 2).eq("equipment_category", item.getValue()));
            Map<String, Object> map = new HashMap<>();
            map.put("name", item.getLabel());
            map.put("value", count1);
            list.add( map);
        });
        return Result.OK(list);
    }


    @GetMapping(value = "/list")
    public Result<IPage<AssetMessage>> queryPageList(AssetMessage assetMessage,
                                                     @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                                     @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                                     HttpServletRequest req) {
        QueryWrapper<AssetMessage> queryWrapper = QueryGenerator.initQueryWrapper(assetMessage, req.getParameterMap());
        Page<AssetMessage> page = new Page<AssetMessage>(pageNo, pageSize);
        IPage<AssetMessage> pageList = assetMessageService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    @GetMapping(value = "/topList")
    public Result<IPage<AssetMessage>> topList(AssetMessage assetMessage,
                                                     @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                                     @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                                     HttpServletRequest req) {
        QueryWrapper<AssetMessage> queryWrapper = QueryGenerator.initQueryWrapper(assetMessage, req.getParameterMap());

        queryWrapper.eq("type", 1);
        queryWrapper.orderByDesc("book_original_value");
        if (pageNo == 1){
            queryWrapper.last("limit 5");
        }else {
            queryWrapper.last("limit 5,1");
        }
        List<AssetMessage> list = assetMessageService.list(queryWrapper);
        Page<AssetMessage> pageList = new Page<AssetMessage>(pageNo, pageSize);
        pageList.setRecords(list);
        pageList.setTotal(6);
        return Result.OK(pageList);
    }


    /**
     * 合同概况统计
     */
    @ApiOperation(value="合同概况统计", notes="合同概况统计")
    @GetMapping(value = "/contractTotal")
    public Result<List<Map<String, Object>>> contractTotal() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map allMap = new HashMap<>();
        QueryWrapper<AssetContractInfo> queryWrapper = new QueryWrapper<>();
        long count = contractInfoService.count();
        allMap.put("name", "all");
        allMap.put("value", count);
        list.add(allMap);
        List<DictModel> items = sysDictService.getDictItems("contract_type");
        items.forEach(item -> {
            queryWrapper.clear();
            long count1 = contractInfoService.count(queryWrapper.eq("contract_type", item.getValue()));
            Map<String, Object> map = new HashMap<>();
            map.put("name", "build"+item.getValue());
            map.put("label", item.getLabel());
            map.put("value", count1);
            list.add( map);
        });
        return Result.OK(list);
    }


    @GetMapping(value = "/contractList")
    public Result<IPage<AssetContractInfo>> contractList(AssetContractInfo assetContractInfo,
                                                          @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                                          @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                                          HttpServletRequest req) {
        QueryWrapper<AssetContractInfo> queryWrapper = QueryGenerator.initQueryWrapper(assetContractInfo, req.getParameterMap());
        Page<AssetContractInfo> page = new Page<AssetContractInfo>(pageNo, pageSize);
        IPage<AssetContractInfo> pageList = contractInfoService.page(page, queryWrapper);
        return Result.OK(pageList);
    }


    @GetMapping(value = "/reminderContractList")
    public Result<IPage<AssetContractInfo>> reminderContractList(AssetContractInfo assetContractInfo,
                                                         @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                                         @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                                         HttpServletRequest req) {
        QueryWrapper<AssetContractInfo> queryWrapper = QueryGenerator.initQueryWrapper(assetContractInfo, req.getParameterMap());
        Page<AssetContractInfo> page = new Page<AssetContractInfo>(pageNo, 9999);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 3);
        Date afterThreeMonths = calendar.getTime();
        // contractEndDate 合同结束日期，在三个月内的
        queryWrapper.lt("contract_end_date", afterThreeMonths);
        queryWrapper.in("contract_status", "1,4".split( ","));
        queryWrapper.orderByAsc("contract_end_date");
        IPage<AssetContractInfo> pageList = contractInfoService.page(page, queryWrapper);
        return Result.OK(pageList);
    }
}
